#!/usr/bin/perl
use strict;
use XML::Parser;

my $INPUT_XML;

my $CODE = "Code";
my $LAT = "Lat";
my $LINECODE1 = "LineCode1";
my $LINECODE2 = "LineCode2";
my $LINECODE3 = "LineCode3";
my $LINECODE4 = "LineCode4";
my $LON = "Lon";
my $NAME = "Name";
my $STATIONTOGETHER1 = "StationTogether1";
my $STATIONTOGETHER2 = "StationTogether2";
my $STATION = "Station";
my $STATIONS = "Stations";
my $STATIONSRESP = "StationsResp";


my $current_element_id = "";
my $buf = "";
my %station = ();

my %lineMap = (
"BL" => "BLUE",
"GR" => "GREEN",
"OR" => "ORANGE",
"RD" => "RED",
"YL" => "YELLOW",
);

my %stations = ();

my $in_Station = 0;


#-----------------------------------------------------------------%%%
# usage - 
#--------------------------------------------------------------------
sub usage{
    my $usage = "Usage:\n\t" ;
    $usage .= "perl $0  input_xml\n";
    return $usage;
}

#-----------------------------------------------------------------%%%
# parse params
#--------------------------------------------------------------------
sub parseParams{
    my $rval = 0;
    
    my $argc = scalar(@ARGV);
    if (0 < $argc ) {
	$INPUT_XML = $ARGV[0];
    } else {
	print &usage();
	$rval = -1;
    }
    
    return $rval;
}

#-----------------------------------------------------------------%%%
sub loadCsv {
  open(CSV,"<stations.csv") || die "Could not open csv\n";

  while(<CSV>) {
        chomp(my $str = $_);

        if($. == 1) { next; }

        my ($apiCode,$apiAltCode,$const,$webName,$webCode,$endOfLine,$line1,$line2,$line3,$line4) = split(/,/, $str);
	my %station = (
	"apiCode" => $apiCode,
	"apiAltCode" => $apiAltCode,
	"const" => $const,
	"webName" => $webName,
	"webCode" => $webCode,
	"endOfLine" => $endOfLine,
	"lines" => ""
	);

	$stations{$apiCode} = \%station;
#print "CSV: |$apiCode|\n";
  }
 


  close(CSV);
}
#-----------------------------------------------------------------%%%
sub start_handler {
    my $p = shift;
    my $el = shift;
    my %attributes = @_;

    if($in_Station == 1) {
    if (($el eq $CODE ) ||
	($el eq $LAT ) ||
	($el eq $LINECODE1 ) ||
	($el eq $LINECODE2 ) ||
	($el eq $LINECODE3 ) ||
	($el eq $LINECODE4 ) ||
	($el eq $LON ) ||
	($el eq $NAME ) ||
	($el eq $STATIONTOGETHER1 ) ||
	($el eq $STATIONTOGETHER2 ) ) {
		$current_element_id = $el;
	   $buf = "";
	}
    } elsif ($el eq $STATION ) {
        $current_element_id = $STATION;
        $in_Station = 1;
        %station = ();
$station{$CODE } = "";
$station{$LAT } = "";
$station{$LINECODE1 } = "";
$station{$LINECODE2 } = "";
$station{$LINECODE3 } = "";
$station{$LINECODE4 } = "";
$station{$LON } = "";
$station{$NAME } = "";
$station{$STATIONTOGETHER1 } = "";
$station{$STATIONTOGETHER2 } = "";
    }

} #start_handler


#-----------------------------------------------------------------%%%
# char_handler - handler for character data.  We only care about 
#  \\SearchGroup\Name element data
#--------------------------------------------------------------------
sub char_handler {
#	print "char:" . join ("\t", @_) . "\n";
	my ($Expat, $el) = @_;
        chomp(my $str = $el);

        if($in_Station == 1) {
	   $str =~ s/^\s+//;
	   $str =~ s/\s+$//;
		$buf .= $str;
        }
} # End of char_handler

sub default_handler {
  # Do Nothing
} 
sub end_handler {
#	print "end:" . join ("\t", @_) . "\n";
	my ($expat, $el) = @_;


    if ($el eq $STATION ) {
        $current_element_id = "";
        $in_Station = 0;

	my $apiCode = $station{$CODE};
	my $apiAltCode = $station{$STATIONTOGETHER1};

        #print $msg . "\n";
	my $s_ref;

	if(exists $stations{$apiCode}) {
	  $s_ref = $stations{$apiCode};
	} elsif(exists $stations{$apiAltCode }) {
	  $s_ref = $stations{$apiAltCode};
	} else {
	  print "Dont know station " . $station{$NAME} . " with code " . $station{$CODE} . "\n";
	  return; 
	}

	my @lines = ( $station{$LINECODE1 } || "", 
                      $station{$LINECODE2 } || "", 
                      $station{$LINECODE3 } || "",
                      $station{$LINECODE4 } || ""
                 );
	$$s_ref{"lines"} = $$s_ref{"lines"} . join(",", @lines);
	$$s_ref{"lat"} = $station{$LAT};
	$$s_ref{"lon"} = $station{$LON};

    } elsif($in_Station == 1) {
    if (($el eq $CODE ) ||
	($el eq $LAT ) ||
	($el eq $LINECODE1 ) ||
	($el eq $LINECODE2 ) ||
	($el eq $LINECODE3 ) ||
	($el eq $LINECODE4 ) ||
	($el eq $LON ) ||
	($el eq $NAME ) ||
	($el eq $STATIONTOGETHER1 ) ||
	($el eq $STATIONTOGETHER2 ) ) {
		$current_element_id = $el;
	   $station{$el} = $buf;
	}
    }

} #end_handler


sub printJava {

print <<EOF;
package app.transitalarm.model;

import static app.transitalarm.util.Constants.BLUE;
import static app.transitalarm.util.Constants.GREEN;
import static app.transitalarm.util.Constants.ORANGE;
import static app.transitalarm.util.Constants.RED;
import static app.transitalarm.util.Constants.YELLOW;

public enum Station {
EOF
foreach my $apiCode (sort keys %stations) {
	  my $s_ref = $stations{$apiCode};

my $apiCode = $$s_ref{"apiCode"};
my $apiAltCode = $$s_ref{"apiAltCode"};
my $const = $$s_ref{"const"};
my $webName = $$s_ref{"webName"};
my $webCode = $$s_ref{"webCode"};
my $endOfLine = $$s_ref{"endOfLine"};
my $lines = $$s_ref{"lines"};

my $altStr = "null";
if($apiAltCode ne "") { $altStr = "\"$apiAltCode\""; }

my $lineStr = "";
foreach my $line (sort split(/,/, $lines)) {
   if(exists $lineMap{$line}) {
       $lineStr .= "," . $lineMap{$line};
}
}

	print "    $const(\"$apiCode\",$altStr,$webCode,\"$webName\",$endOfLine" . "$lineStr),\n";

}

print <<EOF;
    ;
	private final String apiCode;
	private final String apiAltCode;
	private final int webId;
	private final String name;
	private final boolean endOfLine;
	private final String[] lines;

    private Station(final String apiCode, final String apiAltCode, final int webId, final String name, final boolean endOfLine, final String... lines) {
        this.apiCode = apiCode;
        this.apiAltCode = apiAltCode;
    	this.name = name; 
        this.webId = webId;
        this.endOfLine = endOfLine;
        this.lines = lines;
    }

    public String getApiCode() {
		return apiCode;
	}

	public String getApiAltCode() {
		return apiAltCode;
	}

	public int getWebId() {
		return webId;
	}

	public String getName() {
        return name;
    }

    public int getId() {
        return webId;
    }

    public String[] getLines() {
        return lines;
    }

    public boolean isEndOfLine() {
        return endOfLine;
    }
}


EOF

}

#-----------------------------------------------------------------%%%
# main
#--------------------------------------------------------------------
sub main(){
	if( 0 > &parseParams() ) {
		exit(-1);
	} 

	die "Can't find file \"$INPUT_XML\""  unless -f $INPUT_XML;
    
	#&clear_state();

	loadCsv();
	
	my $parser = new XML::Parser(ErrorContext => 2);
	
	$parser->setHandlers(Start => \&start_handler,
						 End   => \&end_handler,
						 Char => \&char_handler,
						 Default => \&default_handler);
	$parser->parsefile($INPUT_XML);

	printJava();

}
#-----------------------------------------------------------------%%%
# live action
#--------------------------------------------------------------------
&main();
1;
__END__



